package com.hailiang.study.javase.java.util.concurrent.fork_join;

import java.util.List;
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
import java.util.stream.Collectors;

/**
 * @author hailiang.jiang
 * @date 2021年11月02 15:33
 */
public class SumTask extends RecursiveTask<Long> {

    private static final int SEQUENTIAL_THRESHOLD = 30;

    private final List<Long> data;

    public SumTask(List<Long> data) {
        this.data = data;
    }

    @Override
    protected Long compute() {
        if (data.size() < SEQUENTIAL_THRESHOLD) {
            long sum = computeSumDirectly();
            System.out.format("Sum of %s: %d\n", data.toString(), sum);
            return sum;
        } else {
            int mid = data.size() / 2;
            SumTask firstSubTask = new SumTask(data.subList(0, mid));
            SumTask secondSubTask = new SumTask(data.subList(mid, data.size()));
            // 执行子任务
            firstSubTask.fork();
            secondSubTask.fork();
            // 等待子任务执行完成，并获取结果
            Long firstSubTaskResult = firstSubTask.join();
            Long secondSubTaskResult = secondSubTask.join();
            return firstSubTaskResult + secondSubTaskResult;
        }
    }

    private long computeSumDirectly() {
        long sum = 0;
        for (Long dt : data) {
            sum += dt;
        }
        return sum;
    }

    public static void main(String[] args) {
        Random random = new Random();

        // 产生320个1~100的数字
        List<Long> data = random
                .longs(320, 1, 100)
                .boxed()
                .collect(Collectors.toList());

        ForkJoinPool pool = new ForkJoinPool();
        SumTask task = new SumTask(data);
        pool.invoke(task);

        System.out.println("Sum: " + pool.invoke(task));
    }
}
